package com.yonyou.pmclouds.procedureinspect.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.billstatus.BillStatusConst;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertMultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.DocCenterProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.ProjectStatusCheckProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.constructionlog.entity.ConstructionLogRefVO;
import com.yonyou.pmclouds.constructionlog.rmiitf.ConstructionLogQuery;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.pmpub.entity.QueryListParam;
import com.yonyou.pmclouds.pmpub.rmiitf.IPageQuerySerivce;
import com.yonyou.pmclouds.procedure.entity.ProcedureRefVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.procedureinspect.mapper.ProcedureInspectBodyMapper;
import com.yonyou.pmclouds.procedureinspect.mapper.ProcedureInspectMapper;
import com.yonyou.pmclouds.procedureinspect.process.PrcInspectBeforeInsertProcess;
import com.yonyou.pmclouds.procedureinspect.process.ProcedureInspectProjectLogPostProcess;
import com.yonyou.pmclouds.processinspect.entity.ProcedureInspectBodyVO;
import com.yonyou.pmclouds.processinspect.entity.ProcedureInspectVO;
import com.yonyou.pmclouds.processinspect.rmiitf.ProcedureInspectRemoteService;
import com.yonyou.pmclouds.project.entity.ProjectRefVO;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.processor.ProjectBillUpdateForUpdate;
import com.yonyou.pmclouds.project.processor.UpdateBillCountForDeleteProcessor;
import com.yonyou.pmclouds.project.processor.UpdateBillCountForInsertProcessor;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.workflow.aspect.PMApprove;
import com.yonyou.pmclouds.workflow.service.rmiitf.IFlowApproveBuziService;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Slf4j
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = ProcedureInspectRemoteService.class)
public class ProcedureInspectRemoteServiceImpl implements ProcedureInspectRemoteService,IFlowApproveBuziService, IPageQuerySerivce<ProcedureInspectVO> {

    @Autowired
    private ProcedureInspectMapper procedureInspectMapper;
    @Autowired
    private ProcedureInspectBodyMapper procedureInspectBodyMapper;
    @Autowired
    private ProjectStatusCheckProcessor<ProcedureInspectVO> projectStatusCheckProcessor;
    @Autowired
    private ProjectSimpleQuery projectService;
    @Autowired
    private ProcedureQuery procedureQuery;
    @Autowired
    private ConstructionLogQuery constructionQuery;
    @Autowired
    private UpdateBillCountForInsertProcessor.UpdateBillCountForInsertProcessorFactory<ProcedureInspectVO> billCountFactory;
    @Autowired
    private WorkqualityQueryService workqualityQueryService;
    @Autowired
    private PictureRemoteService pictureRemoteService;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private ProjectBillUpdateForUpdate.ProjectBillForUpdateProcessorFactory<ProcedureInspectVO> billForUpdateProcessorFactory;
    @Autowired
    private UpdateBillCountForDeleteProcessor.UpdateBillCountForDeleteProcessorFactory<ProcedureInspectVO> billCountDeleteFactory;
    @Autowired
    private ProcedureInspectProjectLogPostProcess procedureInspectProjectLogPostProcess;
    @Autowired
    private DocCenterProcessor docCenterProcessor;

    @Override
    @PMApprove
    public ProcedureInspectVO insertProcedureInspect(ProcedureInspectVO procedureInspectVO) throws BusinessException {

        procedureInspectVO = insertHeadVO(procedureInspectVO);

        insertBodyVOs(procedureInspectVO);

        return procedureInspectVO;
    }

    /**
     * 方法功能描述：保存工序报验表体VO。
     * <p>
     * <b>参数说明</b>
     *
     * @param procedureInspectVO
     * @throws BusinessException
     * @author zhangwce
     * @time 2017年11月15日 下午9:00:42
     */
    private void insertBodyVOs(ProcedureInspectVO procedureInspectVO) throws BusinessException {
        String[] pkRecords = procedureInspectVO.getPk_records();

        if (pkRecords != null && pkRecords.length > 0) {
            List<ProcedureInspectBodyVO> bodyList = new ArrayList<ProcedureInspectBodyVO>();
            for (String pk_record : pkRecords) {
                ProcedureInspectBodyVO bodyVO = new ProcedureInspectBodyVO();
                bodyVO.setPk_process_inspect(procedureInspectVO.getPk_process_inspect());
                bodyVO.setPk_construct_record(pk_record);
                bodyList.add(bodyVO);
            }
            MultiInsertBpTemplate<ProcedureInspectBodyVO> bodyBP = new MultiInsertBpTemplate<ProcedureInspectBodyVO>(procedureInspectBodyMapper);
            bodyBP.addBeforeProcessor(new AuditInfoInsertMultiProcessor<ProcedureInspectBodyVO>());
            bodyBP.insert(bodyList.toArray(new ProcedureInspectBodyVO[0]));
        }
    }

    /**
     * 方法功能描述：保存工序报验表头。
     * <p>
     * <b>参数说明</b>
     *
     * @param procedureInspectVO
     * @return
     * @throws BusinessException
     * @author zhangwce
     * @time 2017年11月15日 下午8:59:26
     */
    private ProcedureInspectVO insertHeadVO(ProcedureInspectVO procedureInspectVO) throws BusinessException {
        SingleInsertBpTemplate<ProcedureInspectVO> headBP = new SingleInsertBpTemplate<ProcedureInspectVO>(procedureInspectMapper);
        headBP.addBeforeProcessor(new PrcInspectBeforeInsertProcess(procedureInspectMapper, procedureInspectBodyMapper));
        headBP.addBeforeProcessor(new AuditInfoInsertProcessor<ProcedureInspectVO>());
        headBP.addBeforeProcessor(projectStatusCheckProcessor);
        headBP.addAfterProcessor(billCountFactory.getProcessor(BillTypeConst.PROCEDUREINSPECT_BILLTYPE));
        //智能日志
        headBP.addAfterProcessor(procedureInspectProjectLogPostProcess);
        procedureInspectVO = headBP.insert(procedureInspectVO);
        return procedureInspectVO;
    }


    @Override
    public List<ProcedureInspectVO> queryPrcInspectByPrj(String pk_project) throws BusinessException {

        List<ProcedureInspectVO> prcInspectList = procedureInspectMapper.queryPrcInspectByPrj(pk_project);
        if (prcInspectList == null || prcInspectList.size() == 0) {
            return null;
        }
        batchFillHeadBusiInfo(prcInspectList);

        return prcInspectList;
    }


    @Override
    public ProcedureInspectVO queryPrcInspectDetail(String pk_procedure_inspect) throws BusinessException {

        ProcedureInspectVO procedureInspectVO = procedureInspectMapper.getById(pk_procedure_inspect);

        fillHeadBusiInfo(procedureInspectVO);

        if (procedureInspectVO == null) {
            return null;
        }
        List<ProcedureInspectBodyVO> bodyList = procedureInspectBodyMapper.queryByPkParents(new String[]{pk_procedure_inspect});

        List<String> pkRecordList = new ArrayList<String>();
        for (ProcedureInspectBodyVO bodyVO : bodyList) {
            pkRecordList.add(bodyVO.getPk_construct_record());
        }

        ConstructionLogRefVO[] recordRefVOs = constructionQuery.queryByIds(pkRecordList.toArray(new String[0]));
        Map<String, ConstructionLogRefVO> pkRecordMap = new HashMap<String, ConstructionLogRefVO>();
        // 检查标准pks
        Set<String> inspectstandardPks = new HashSet<>();
        // 工序pks
        Set<String> procedurePks = new HashSet<>();
        if (recordRefVOs != null) {
            for (ConstructionLogRefVO refVO : recordRefVOs) {
                pkRecordMap.put(refVO.getPk_constructionlog(), refVO);
                inspectstandardPks.add(refVO.getPk_inspectstandard());
                procedurePks.add(refVO.getPk_process());
            }
        }
        // 根据标准pks获取标准内容
        Map<String, WorkqualityVO> stringWorkqualityVOMap = workqualityQueryService.queryByIDs(inspectstandardPks.toArray(new String[inspectstandardPks.size()]));
        // 获取施工记录对应的图片信息
        Map<String, List<PictureVO>> picsByPkBillMap = pictureRemoteService.getPicsByPkBill(pkRecordList.toArray(new String[pkRecordList.size()]));
        // 工序
        Map<String, ProcedureRefVO> prcRefMap = procedureQuery.queryRefs(procedurePks.toArray(new String[procedurePks.size()]));
        String tempRecord = null;
        for (ProcedureInspectBodyVO bodyVO : bodyList) {

            tempRecord = bodyVO.getPk_construct_record();
            if (pkRecordMap.get(tempRecord) != null) {
                bodyVO.setCheck_object(pkRecordMap.get(tempRecord).getInspectarea());
                bodyVO.setRecord_creator(pkRecordMap.get(tempRecord).getCreator());
                bodyVO.setRecord_creationtime(pkRecordMap.get(tempRecord).getCreationtime());
                // 添加检查标准名称
                if (stringWorkqualityVOMap.get(pkRecordMap.get(tempRecord).getPk_inspectstandard()) != null) {
                    bodyVO.setInspectstandardName(stringWorkqualityVOMap.get(pkRecordMap.get(tempRecord).getPk_inspectstandard()).getCheckname());
                }
                // 图片个数
                if (picsByPkBillMap.get(tempRecord) != null) {
                    bodyVO.setPicCount(picsByPkBillMap.get(tempRecord).size());
                }
                // 工序名称（施工记录）
                if (prcRefMap.get(pkRecordMap.get(tempRecord).getPk_process()) != null) {
                    bodyVO.setProcessName(prcRefMap.get(pkRecordMap.get(tempRecord).getPk_process()).getSname());
                }
            }
        }


        procedureInspectVO.setBodyVOs(bodyList.toArray(new ProcedureInspectBodyVO[0]));

        return procedureInspectVO;
    }

    /**
     * 方法功能描述：工序报验表头VO设置必要的业务信息。
     * <p>
     * <b>参数说明</b>
     *
     * @param procedureInspectVO
     * @throws BusinessException
     * @author zhangwce
     * @time 2017年11月20日 下午11:26:41
     */
    private void fillHeadBusiInfo(ProcedureInspectVO procedureInspectVO) throws BusinessException {
        List<ProcedureInspectVO> queryList = new ArrayList<ProcedureInspectVO>();
        queryList.add(procedureInspectVO);
        batchFillHeadBusiInfo(queryList);
    }

    /**
     * 方法功能描述：批量为工序报验表头VO设置必要的业务信息。
     * <p>
     * <b>参数说明</b>
     *
     * @param queryList
     * @return
     * @throws BusinessException
     * @author zhangwce
     * @time 2017年11月20日 下午11:22:07
     */
    private List<ProcedureInspectVO> batchFillHeadBusiInfo(List<ProcedureInspectVO> queryList) throws BusinessException {
        //项目主键与工序报验表头的对应关系
        Map<String, List<ProcedureInspectVO>> prjPrcMap = new HashMap<String, List<ProcedureInspectVO>>();
        //工序主键与工序报验单表头的对应关系
        Map<String, List<ProcedureInspectVO>> prcInspectMap = new HashMap<String, List<ProcedureInspectVO>>();
        // 工序报验pks
        Set<String> procedureInspectPks = new HashSet<>();
        // 项目档案组织
        Set<String> pkOrgSet = new HashSet<>();

        for (ProcedureInspectVO queryVO : queryList) {
            if (prjPrcMap.get(queryVO.getPk_project()) == null) {
                prjPrcMap.put(queryVO.getPk_project(), new ArrayList<ProcedureInspectVO>());
            }

            prjPrcMap.get(queryVO.getPk_project()).add(queryVO);

            if (prcInspectMap.get(queryVO.getPk_procedure()) == null) {
                prcInspectMap.put(queryVO.getPk_procedure(), new ArrayList<ProcedureInspectVO>());
            }
            prcInspectMap.get(queryVO.getPk_procedure()).add(queryVO);
            // 收集工序报验pks
            procedureInspectPks.add(queryVO.getPk_process_inspect());
        }

        Map<String, ProjectRefVO> prjRefMap = projectService.queryRefs(prjPrcMap.keySet().toArray(new String[0]));
        Map<String, ProcedureRefVO> prcRefMap = procedureQuery.queryRefs(prcInspectMap.keySet().toArray(new String[0]));

        List<ProcedureInspectVO> resultList = new ArrayList<ProcedureInspectVO>();

        List<ProcedureInspectVO> prcList = null;
        // 设置项目名称的值
        for (String pk_project : prjPrcMap.keySet()) {
            prcList = prjPrcMap.get(pk_project);
            for (ProcedureInspectVO prcVO : prcList) {
                prcVO.setProject_name(prjRefMap.get(pk_project).getSname());
                prcVO.setProject_code(prjRefMap.get(pk_project).getScode());
                resultList.add(prcVO);
            }

            pkOrgSet.add(prjRefMap.get(pk_project).getPkOrg());
        }
        //设置组织名称
        OrganizationVO[] organizationVOs = organizationQuery.queryByPkSrcs(RuntimeEnvironment.getTenantId(),pkOrgSet.toArray(new String[0]));

        Map<String,OrganizationVO> orgMap = new HashMap<>();

        for (OrganizationVO orgVO : organizationVOs){
            orgMap.put(orgVO.getPkSrc(),orgVO);
        }
        String pkTemp = "";
        for (String pk_project : prjPrcMap.keySet()) {
            prcList = prjPrcMap.get(pk_project);
            for (ProcedureInspectVO prcVO : prcList) {
                pkTemp = prjRefMap.get(prcVO.getPk_project()).getPkOrg();
                if(orgMap.get(pkTemp)!=null){
                    prcVO.setOrgName(orgMap.get(pkTemp).getSname());
                }
            }
        }

        // 设置工序名称的值
        for (ProcedureInspectVO resultVO : resultList) {
            if (prcRefMap.get(resultVO.getPk_procedure()) != null)
                resultVO.setProcedure_name(prcRefMap.get(resultVO.getPk_procedure()).getSname());
        }
        if (procedureInspectPks.size() > 0) {
            // 填充施工记录主键
            List<ProcedureInspectBodyVO> bodyList = procedureInspectBodyMapper.queryByPkParents(procedureInspectPks.toArray(new String[procedureInspectPks.size()]));
            for (ProcedureInspectVO procedureInspectVO : queryList) {
                // 施工记录pks
                Set<String> constructPks = new HashSet<>();
                for (ProcedureInspectBodyVO inspectBodyVO : bodyList) {
                    if (procedureInspectVO.getPk_process_inspect().equals(inspectBodyVO.getPk_process_inspect())) {
                        constructPks.add(inspectBodyVO.getPk_construct_record());
                    }
                }
                procedureInspectVO.setPk_records(constructPks.toArray(new String[constructPks.size()]));
            }
        }
        return resultList;
    }

    public ProcedureInspectVO approve(String pkProcedureInspect, byte billStatus) throws BusinessException {

        ProcedureInspectVO  procedureInspectVO = procedureInspectMapper.getById(pkProcedureInspect);

        procedureInspectVO.setBillstatus(billStatus);

        SingleUpdateBpTemplate<ProcedureInspectVO> headBP = new SingleUpdateBpTemplate<>(procedureInspectMapper, new String[]{ProcedureInspectVO.APPROVE_OPINION, ProcedureInspectVO.BILLSTATUS});
        headBP.addAfterProcessor(billForUpdateProcessorFactory.getProcessor(BillTypeConst.PROBLEMLOG_BILLTYPE));
        if(BillStatusConst.COMMON_APPROVED_STATUS == billStatus)
            headBP.addAfterProcessor(docCenterProcessor);

        return headBP.update(procedureInspectVO);
    }

    @Override
    public List<ConstructionLogRefVO> queryRecordForPrcInspect(String pk_project) throws BusinessException {
        // 根据项目查询项目下的施工记录
        ConstructionLogRefVO[] recordVOs = constructionQuery.queryRefsByProject(pk_project);

        if (recordVOs == null || recordVOs.length == 0)
            return null;

        Map<String, ConstructionLogRefVO> recordMap = new HashMap<String, ConstructionLogRefVO>();

        for (ConstructionLogRefVO viewVO : recordVOs) {
            recordMap.put(viewVO.getPk_constructionlog(), viewVO);
        }

        // 查询出已经进行过工序报验的施工记录主键
        List<String> recordList = procedureInspectBodyMapper.queryInspectedRecord(recordMap.keySet().toArray(new String[0]),BillStatusConst.COMMON_REJECT_STATUS);
        // 获得施工记录单中的工序集合，用于批量查询工序信息
        Set<String> procSet = new HashSet<>();

        Map<String, ConstructionLogRefVO> canInspectRecordMap = new HashMap<String, ConstructionLogRefVO>();

        String tempProcess = null;
        for (String pkRecord : recordMap.keySet()) {

            if (recordList.contains(pkRecord)) {
                continue;
            }
            // 过滤掉工序为空的施工记录
            tempProcess = recordMap.get(pkRecord).getPk_process();
            if (tempProcess == null || "".equals(tempProcess) || "~".equals(tempProcess)) {
                continue;
            }

            procSet.add(recordMap.get(pkRecord).getPk_process());
            canInspectRecordMap.put(pkRecord, recordMap.get(pkRecord));
        }

        if (canInspectRecordMap == null || canInspectRecordMap.size() == 0)
            return null;

        List<ConstructionLogRefVO> resultList = fillProcedureInfo(canInspectRecordMap, procSet);

        return resultList;
    }

    /**
     * 方法功能描述：施工记录参照增添工序信息。
     * <p>
     * <b>参数说明</b>
     *
     * @param recordMap
     * @param procSet
     * @return
     * @throws BusinessException
     * @author zhangwce
     * @time 2017年11月29日 下午2:37:23
     */
    private List<ConstructionLogRefVO> fillProcedureInfo(Map<String, ConstructionLogRefVO> recordMap,
                                                         Set<String> procSet) throws BusinessException {
        //根据工序ID查询工序
        Map<String, ProcedureRefVO> prcRefMap = procedureQuery.queryRefs(procSet.toArray(new String[0]));

        List<ConstructionLogRefVO> resultList = new ArrayList<ConstructionLogRefVO>();


        for (ConstructionLogRefVO recordVO : recordMap.values()) {
            if (prcRefMap.get(recordVO.getPk_process()) == null)
                continue;

            recordVO.setProcess_name(prcRefMap.get(recordVO.getPk_process()).getSname());
            resultList.add(recordVO);
        }
        return resultList;
    }

    @Override
    public boolean queryRefByIds(String code, String[] ids) throws BusinessException {
        boolean flag = false;
        Integer count = procedureInspectMapper.selectRefByCode(code, ids);
        if (count != null && count > 0) {
            flag = true;
        }
        return flag;
    }

    /**
     * 根据参数进行数据查询
     *
     * @param params
     * @return java.util.List<com.yonyou.pmclouds.processinspect.entity.ProcedureInspectVO>
     * @author yzx
     * @date 2018/5/28 16:10
     */
    @Override
    public List<ProcedureInspectVO> queryVosByParams(Map<String, Object> params) throws BusinessException {
        List<ProcedureInspectVO> procedureInspectVOList = procedureInspectMapper.queryVosByParams(params);
        // 必要数据填充
        batchFillHeadBusiInfo(procedureInspectVOList);
        return procedureInspectVOList;
    }

    /**
     * 本方法可能未填充所有数据，如信息不足请自己填充
     *
     * @param procedureinspectpks
     * @return java.util.List<com.yonyou.pmclouds.processinspect.entity.ProcedureInspectVO>
     * @author yzx
     * @date 2018/6/1 19:37
     */
    @Override
    public List<ProcedureInspectVO> queryByProcedureInspectPks(String[] procedureinspectpks) throws BusinessException {
        // 通过工序报验pks,获取所有工序报验
        List<ProcedureInspectVO> inspectVOList = procedureInspectMapper.queryByPks(procedureinspectpks);
        // 工序所有pk
        Set<String> procedurePks = new HashSet<>();
        // 工序报验所有pks
        Set<String> procedureInspectPks = new HashSet<>();
        for (ProcedureInspectVO procedureInspectVO : inspectVOList) {
            procedurePks.add(procedureInspectVO.getPk_procedure());
            procedureInspectPks.add(procedureInspectVO.getPk_process_inspect());
        }
        // 填充施工记录主键
        List<ProcedureInspectBodyVO> bodyList = procedureInspectBodyMapper.queryByPkParents(procedureInspectPks.toArray(new String[procedureInspectPks.size()]));
        for (ProcedureInspectVO procedureInspectVO : inspectVOList) {
            // 施工记录pks
            Set<String> constructPks = new HashSet<>();
            for (ProcedureInspectBodyVO inspectBodyVO : bodyList) {
                if (procedureInspectVO.getPk_process_inspect().equals(inspectBodyVO.getPk_process_inspect())) {
                    constructPks.add(inspectBodyVO.getPk_construct_record());
                }
            }
            procedureInspectVO.setPk_records(constructPks.toArray(new String[constructPks.size()]));
        }
        //根据工序ID查询工序
        Map<String, ProcedureRefVO> procedureRefVOMap = procedureQuery.queryRefs(procedurePks.toArray(new String[procedurePks.size()]));
        // 进行填充名字
        for (ProcedureInspectVO procedureInspectVO : inspectVOList) {
            ProcedureRefVO procedureRefVO = procedureRefVOMap.get(procedureInspectVO.getPk_procedure());
            if (procedureRefVO != null) {
                procedureInspectVO.setProcedure_name(procedureRefVOMap.get(procedureInspectVO.getPk_procedure()).getSname());
            }
        }
        return inspectVOList;
    }

    @Override
    public PageObject<Object> queryByCondition(String[] pkProjects, String[] creators, String startDate, String endDate, int[] billStatus, int pageStart, int pageSize) throws BusinessException {

        int count = procedureInspectMapper.countByCondition(pkProjects, creators, startDate, endDate, billStatus);

        ProcedureInspectVO[] procedureInspectVOs = procedureInspectMapper.queryByCondition(pkProjects, creators, startDate, endDate, billStatus, pageStart, pageSize);

        if(ArrayUtils.isEmpty(procedureInspectVOs))
            return new PageObject<Object>(procedureInspectVOs,0,pageStart) ;
        // 设置工序报验的施工记录单数
        setBodyNum(procedureInspectVOs);
        // 补全参照信息
        return new PageObject<Object>(setRefFiledInfo(procedureInspectVOs),count,pageStart);
    }

    private void setBodyNum(ProcedureInspectVO[] procedureInspectVOs) {
        // 表头PK和表体VO的对应关系
        Map<String,List<ProcedureInspectBodyVO>> procBodyMap = getProcBodyMap(procedureInspectVOs);

        String tempPk = "";
        for (ProcedureInspectVO headVO :procedureInspectVOs){
            tempPk = headVO.getPk_process_inspect();
            if(procBodyMap.get(tempPk) == null ||
                    procBodyMap.get(tempPk).size() == 0)
                headVO.setBodyNum(0);
            headVO.setBodyNum(procBodyMap.get(tempPk).size());
        }
    }

    private Map<String,List<ProcedureInspectBodyVO>> getProcBodyMap(ProcedureInspectVO[] procedureInspectVOs) {
        String[] pkBills = new String[procedureInspectVOs.length];

        for (int i=0;i<procedureInspectVOs.length;i++){
            pkBills[i] = procedureInspectVOs[i].getPk_process_inspect();
        }

        List<ProcedureInspectBodyVO> bodyVOList = procedureInspectBodyMapper.queryByPkParents(pkBills);

        Map<String,List<ProcedureInspectBodyVO>> pkBillAndBodyList = new HashMap<String,List<ProcedureInspectBodyVO>>();

        for (ProcedureInspectBodyVO bodyVO : bodyVOList){
            if(pkBillAndBodyList.get(bodyVO.getPk_process_inspect())==null){
                pkBillAndBodyList.put(bodyVO.getPk_process_inspect(),new ArrayList<ProcedureInspectBodyVO>());
            }
            pkBillAndBodyList.get(bodyVO.getPk_process_inspect()).add(bodyVO);
        }

        return pkBillAndBodyList;
    }

    @Override
    public SuperVO approveByPkBill(String pk_bill, byte billStatus) throws BusinessException {
        return approve(pk_bill,billStatus);
    }

    @Override
    public SuperVO rejectByPkBill(String pk_bill) throws BusinessException {
        return approve(pk_bill,BillStatusConst.COMMON_REJECT_STATUS);
    }

    @Override
    public SuperVO queryDetailForWorkFlow(String pk_bill) throws BusinessException {
        return procedureInspectMapper.getById(pk_bill);
    }

    @Override
    public int countByProject(QueryListParam param) throws BusinessException{

        int count = procedureInspectMapper.countByCondition(new String[]{param.getPkProject()}, null,  param.getStartDate(), param.getEndDate(), null);

        return count;
    }

    @Override
    public ProcedureInspectVO[] queryByProject(QueryListParam param) throws BusinessException {
        ProcedureInspectVO[] vos = procedureInspectMapper.queryByCondition(new String[]{param.getPkProject()}, null,  param.getStartDate(), param.getEndDate(), null,param.getPageStart(),param.getPageSize());

        return setRefFiledInfo(vos);
    }

    @Override
    public String getBillType() {
        return BillTypeConst.PROCEDUREINSPECT_BILLTYPE;
    }

    /**
     * 处理参照字段，非必输项需校验空
     *
     * @param vos
     * @return
     * @throws BusinessException
     */
    private ProcedureInspectVO[] setRefFiledInfo(ProcedureInspectVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return new ProcedureInspectVO[0];
        }

        Set<String> procSet = new HashSet<String>();
        Set<String> projectSet = new HashSet<String>();
        Set<String> pkSet = new HashSet<String>();

        for (ProcedureInspectVO vo:
                vos) {
            procSet.add(vo.getPk_procedure());
            projectSet.add(vo.getPk_project());
            pkSet.add(vo.getPk_process_inspect());
        }

        Map<String,ProcedureRefVO>  procedureRefVOMap = procedureQuery.queryRefs(procSet.toArray(new String[0]));

        Map<String,ProjectVO> projectVOMap = projectService.queryProjects(projectSet.toArray(new String[0]));

        for (ProcedureInspectVO vo:
                vos) {
            vo.setProcedure_name(procedureRefVOMap.get(vo.getPk_procedure()) == null ? null:procedureRefVOMap.get(vo.getPk_procedure()).getSname());
            vo.setProject_name(projectVOMap.get(vo.getPk_project()) == null ? null:projectVOMap.get(vo.getPk_project()).getSname());
            vo.setProject_code(projectVOMap.get(vo.getPk_project()) == null ? null:projectVOMap.get(vo.getPk_project()).getScode());
        }

        return vos;
    }

    @Override
    public SuperVO deleteBill(SuperVO businessVO) throws BusinessException {
        SingleDeleteBpTemplate<ProcedureInspectVO> deleteBpTemplate = new SingleDeleteBpTemplate<>(procedureInspectMapper);
        deleteBpTemplate.addAfterProcessor(billCountDeleteFactory.getProcessor(BillTypeConst.PROCEDUREINSPECT_BILLTYPE));
        return deleteBpTemplate.delete((ProcedureInspectVO) businessVO);
    }

    @Override
    public Object getMapper() {
        return procedureInspectMapper;
    }
}
